package cn.kinoko.service.common.export.component;

import cn.kinoko.common.code.ErrorCodeEnum;
import cn.kinoko.common.utils.ExceptionUtil;
import cn.kinoko.config.ExportConfig;
import cn.kinoko.service.common.export.ExportTaskStatusEnum;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.LinkedList;
import java.util.List;
import java.util.Optional;

/**
 * @author kk
 */
@Slf4j
@Component
@AllArgsConstructor
public class ExportQueue {

    private final ExportConfig config;
    private final LinkedList<ExportTask> QUEUE = new LinkedList<>();

    /**
     * 入队
     */
    public ExportTask push(ExportTask task) {
        // 判断是否存在队列中
        Optional<ExportTask> exportTask = QUEUE.stream()
                .filter(queueTask -> queueTask.getTaskId().equals(task.getTaskId())).findAny();
        if (exportTask.isPresent()) {
            return exportTask.get();
        }
        // 队列已满
        if (QUEUE.size() >= config.getMaxQueueSize()) {
            ExceptionUtil.throwOut(ErrorCodeEnum.SYSTEM_ERROR_B0501);
        }
        task.setRange(QUEUE.size() + 1);
        QUEUE.add(task);
        log.info("导出任务入队成功，当前队列长度：{}", QUEUE.size());
        return null;
    }

    /**
     * 出队
     */
    public void pop() {
        QUEUE.pop();
        resort();
    }

    /**
     * 根据任务id移除任务
     */
    public void removeByTaskId(String taskId) {
        QUEUE.removeIf(task -> task.getTaskId().equals(taskId));
        resort();
    }

    /**
     * 重新排序
     */
    private void resort() {
        // 重新排序
        for (int i = 0; i < QUEUE.size(); i++) {
            QUEUE.get(i).setRange(i + 1);
        }
    }

    /**
     * 获取下一个任务
     */
    public ExportTask next() {
        return QUEUE.stream().filter(task -> task.getStatus() == ExportTaskStatusEnum.WAITING).findFirst().orElse(null);
    }

    public List<ExportTask> getQueueByUid(Long uid) {
        return QUEUE.stream().filter(task -> task.getUid().equals(uid)).toList();
    }

    public ExportTask getTaskByTaskId(String taskId) {
        return QUEUE.stream().filter(task -> task.getTaskId().equals(taskId)).findFirst().orElse(null);
    }

}
